package com.martin.dms.services.impl;

import java.util.ArrayList;
import java.util.List;

import com.martin.dms.dataservices.CategoryDataService;
import com.martin.dms.dataservices.ItemDataService;
import com.martin.dms.factories.ItemFactory;
import com.martin.dms.model.Category;
import com.martin.dms.model.Item;
import com.martin.dms.services.ItemService;
import com.martin.dms.services.util.ServicesUtil;

/**
 * Implementation of the <code>ItemService</code>.
 * 
 * @author mtsvetkov
 */
public class ItemServiceImpl implements ItemService {

    private ItemDataService itemDataService;

    private ItemFactory itemFactory;

    private CategoryDataService categoryDataService;

    /**
     * Constructor.
     * 
     * @param itemDataService - data service for the item entity.
     * @param itemFactory - factory service for the item entity.
     * @param categoryDataService - data service for the category entity.
     */
    public ItemServiceImpl(ItemDataService itemDataService, ItemFactory itemFactory,
            CategoryDataService categoryDataService) {
        this.itemDataService = itemDataService;
        this.itemFactory = itemFactory;
        this.categoryDataService = categoryDataService;
    }

    /**
     * {@inheritDoc}
     */
    public Item get(long id) {
        return itemDataService.get(id);
    }

    /**
     * {@inheritDoc}
     */
    public void delete(long id) {
        itemDataService.delete(id);
    }

    /**
     * {@inheritDoc}
     */
    public void create(String name, long categoryId, int price, String description, byte[] image) {
        Category category = categoryDataService.get(categoryId);
        Item item = itemFactory.create(name, price, description, image, category);
        itemDataService.create(item);
    }

    /**
     * {@inheritDoc}
     */
    public void update(long id, String name, long categoryId, int price, String description, byte[] image) {
        itemDataService.updateName(id, name);
        itemDataService.updateCategory(id, categoryId);
        itemDataService.updatePrice(id, price);
        itemDataService.updateDescription(id, description);
        itemDataService.updateImage(id, image);
    }

    /**
     * {@inheritDoc}
     */
    public List<Item> getAllItemsWithNoCategoryAssigned() {
        List<Item> items = itemDataService.getAll();
        List<Item> result = new ArrayList<Item>();
        for (Item item : items) {
            if (item.getCategory() == null) {
                result.add(item);
            }
        }
        return result;
    }

    /**
     * {@inheritDoc}
     */
    public List<Item> findByNameAndCategory(String nameFilter, long categoryId) {
        Category category = categoryDataService.get(categoryId);
        List<Item> items = null;
        if (category != null) {
            items = new ArrayList<Item>(category.getItems());
        } else {
            items = itemDataService.getAll();
        }
        return filterByName(items, nameFilter);
    }

    /**
     * {@inheritDoc}
     */
    public List<Item> findByName(String nameFilter) {
        List<Item> items = itemDataService.getAll();
        return filterByName(items, nameFilter);
    }

    private List<Item> filterByName(List<Item> items, String nameFilter) {
        nameFilter = ServicesUtil.parseFilterString(nameFilter);
        List<Item> result = new ArrayList<Item>();
        for (Item item : items) {
            if (item.getName().toLowerCase().matches(nameFilter)) {
                result.add(item);
            }
        }
        return result;
    }
}
